package com.deer.wms.ASN.manage.service.impl;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.deer.wms.ASN.manage.constant.AsnManageConstant;
import com.deer.wms.ASN.manage.dao.AcceptRecordMapper;
import com.deer.wms.ASN.manage.dao.AsnDetailMapper;
import com.deer.wms.ASN.manage.dao.AsnMasterMapper;
import com.deer.wms.ASN.manage.dao.QcRecordMapper;
import com.deer.wms.ASN.manage.model.asn.AsnDetail;
import com.deer.wms.ASN.manage.model.asn.AsnDetailCriteria;
import com.deer.wms.ASN.manage.model.asn.AsnDetailDto;
import com.deer.wms.ASN.manage.model.asn.AsnMaster;
import com.deer.wms.ASN.manage.model.buy.RequestBuy;
import com.deer.wms.ASN.manage.model.buy.RequestBuyDetail;
import com.deer.wms.ASN.manage.model.buy.RequestBuyDetailCriteria;
import com.deer.wms.ASN.manage.model.buy.RequestBuyDetailDto;
import com.deer.wms.ASN.manage.model.in.AcceptInsert;
import com.deer.wms.ASN.manage.model.in.AcceptRecord;
import com.deer.wms.ASN.manage.model.in.AcceptRecordCriteria;
import com.deer.wms.ASN.manage.model.in.AcceptRecordExcel;
import com.deer.wms.ASN.manage.model.qc.QcRecord;
import com.deer.wms.ASN.manage.service.*;
import com.deer.wms.base.system.dao.ErpBackRecordMapper;
import com.deer.wms.base.system.model.*;
import com.deer.wms.base.system.model.Item.ItemInfo;
import com.deer.wms.base.system.service.CellInfoService;
import com.deer.wms.base.system.service.ItemInfoService;
import com.deer.wms.base.system.service.PackDetailService;
import com.deer.wms.intercept.common.data.CurrentUser;
import com.deer.wms.inventory.constant.InventoryConstant;
import com.deer.wms.inventory.model.Inventory.*;
import com.deer.wms.inventory.service.InventoryService;
import com.deer.wms.inventory.service.InventoryTransactService;
import com.deer.wms.inventory.service.ItemBatchService;
import com.deer.wms.inventory.service.SerialNoService;
import com.deer.wms.inventory.service.impl.InventoryTransactServiceImpl;
import com.deer.wms.project.root.core.result.CommonCode;
import com.deer.wms.project.root.core.result.ResultGenerator;
import com.deer.wms.project.root.exception.ServiceException;
import com.deer.wms.project.root.service.SuperServiceImpl;
import com.deer.wms.project.root.util.BeanUtils;
import com.deer.wms.project.root.util.DateUtils;
import com.deer.wms.project.root.util.StringUtils;
import com.deer.wms.review.manage.service.BillRecordService;
import com.deer.wms.system.manage.constant.SystemManageConstant;
import com.deer.wms.system.manage.model.ware.WareInfo;
import com.deer.wms.system.manage.service.CodeRuleService;
import com.deer.wms.system.manage.service.OrganizationService;
import com.deer.wms.system.manage.service.ValidatorService;
import com.deer.wms.system.manage.service.WareInfoService;
import com.deer.wms.ware.task.config.StrategyErpService;
import com.deer.wms.ware.task.model.SO.SoDetail;
import com.deer.wms.ware.task.model.SO.SoMaster;
import com.deer.wms.ware.task.model.pickTask.PickTask;
import com.deer.wms.ware.task.model.pushErp.beasAssist.BaseAssist;
import com.deer.wms.ware.task.service.PickTaskService;
import com.deer.wms.ware.task.service.PushErpService;
import com.deer.wms.ware.task.service.SoDetailService;
import com.deer.wms.ware.task.service.SoMasterService;
import com.google.common.base.Preconditions;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.Column;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

import static com.deer.wms.project.root.util.CollectionUtils.convertMap;


/**
 * @author 郭靖勋
 * @since 2019/12/18
 */
@Service
@Transactional //事务回滚
@Slf4j
public class AcceptRecordServiceImpl extends SuperServiceImpl<AcceptRecordMapper, AcceptRecord> implements AcceptRecordService {
    @Autowired
    private AcceptRecordMapper acceptRecordMapper;

    @Autowired
    private ItemBatchService itemBatchService;

    @Autowired
    private InventoryTransactServiceImpl inventoryTransactService;

    @Autowired
    private AcceptRecordService acceptRecordService;

    @Autowired
    private AsnMasterService asnMasterService;

    @Autowired
    private AsnDetailService asnDetailService;

    @Autowired
    private RequestBuyService requestBuyService;

    @Autowired
    private RequestBuyDetailService requestBuyDetailService;

    @Autowired
    private SerialNoService serialNoService;

    @Autowired
    private BillRecordService billRecordService;

    @Autowired
    private ValidatorService validatorService;

    @Autowired
    private CellInfoService cellInfoService;

    @Autowired
    private AcceptExService acceptExService;

    @Autowired
    private QcMasterService qcMasterService;

    @Autowired
    private ItemInfoService itemInfoService;

    @Autowired
    private OrganizationService organizationService;

    @Autowired
    private WareInfoService wareInfoService;

    @Autowired
    private CodeRuleService codeRuleService;

    @Autowired
    private PackDetailService packDetailService;

    @Autowired
    private AsnMasterMapper asnMasterMapper;

    @Autowired
    private AsnDetailMapper asnDetailMapper;

    @Autowired
    private QcRecordMapper qcRecordMapper;

    @Autowired
    private ErpBackRecordMapper erpBackRecordMapper;

    @Autowired
    private SoMasterService soMasterService;

    @Autowired
    private SoDetailService soDetailService;

    @Autowired
    private PushErpService pushErpService;


    public String getNextBoxCode() {
        return validatorService.getNextId("box_info").toString();
    }

    @Override
    public List<AcceptRecord> findList(AcceptRecordCriteria criteria) {
        return acceptRecordMapper.findList(criteria);
    }

    @Override
    public Integer accept(AcceptInsert acceptInsert) {
        //Step0.准备数据
        //使用批次策略生成
        //获取固定格式批次码 [yyyyMMdd流水号] 批次可能存在 也可能不存在
        QueryWrapper<ItemBatch> queryWrapper = new QueryWrapper();
        queryWrapper.eq("detail_no", acceptInsert.getAsnBillNo());
        queryWrapper.eq("in_date", DateUtil.today());
        queryWrapper.last("limit 1");
        ItemBatch itemBatch = itemBatchService.getOne(queryWrapper);
        //如果启用了批次管理
        if (ObjectUtil.isEmpty(itemBatch)) {
            itemBatch = itemBatchService.createSimpleItemBatch(acceptInsert.getAsnBillNo());
        }
        acceptInsert.setBatchId(itemBatch.getBatchId());
        if (ObjectUtil.isNotEmpty(acceptInsert.getBatchName())) {
            acceptInsert.setBatchName(acceptInsert.getBatchName());
        } else {
            acceptInsert.setBatchName(itemBatch.getBatchName());
        }
        //Step1.创建收货单并确认
        List<AcceptRecord> list = this.saveAndConfirmAcceptRecord(ListUtil.toList(acceptInsert));

        return list.get(0).getId();
    }

    /**
     * 校验收货数据是否合法，合法后才允许后续的操作
     *
     * @param acceptInsert acceptInsert
     */
    private void validateAndPrepareAcceptData(AcceptInsert acceptInsert) {
        //仓库
        WareInfo wareInfo = wareInfoService.getById(acceptInsert.getWareId());
        Preconditions.checkNotNull(wareInfo, "根据仓库id[%s]获取仓库失败!", new Object[]{acceptInsert.getWareId()});
        acceptInsert.setWareName(wareInfo.getWareName());

        acceptInsert.setItemName(acceptInsert.getItemName());

//        }
        //TODO:容器
    }

    /**
     * 收货单确认后更新
     *
     * @param acceptRecord
     */
    private void updateASNState(AcceptRecord acceptRecord) {
        AsnDetail asnDetail = asnDetailService.getOneByField("detail_no", acceptRecord.getAsnDetailNo());
        //更新ASN明细
        asnDetail.setAcceptQuantity(acceptRecord.getQuantity() + asnDetail.getAcceptQuantity());
        asnDetail.setAcceptTime(acceptRecord.getAcceptTime());
        if (asnDetail.getAcceptQuantity().equals(asnDetail.getExpectQuantity())) {
            asnDetail.setState(AsnManageConstant.ASN_STATE_ALL);
        } else {
            asnDetail.setState(AsnManageConstant.ASN_STATE_PARTED);
        }
        if (acceptRecord.getQuantity() > asnDetail.getExpectQuantity()) {
            asnDetail.setState(AsnManageConstant.ASN_STATE_OVER);
        }
//        asnDetail.setExState(0);???
        asnDetailService.updateById(asnDetail);

        //更新ASN状态，若明细全部验收则入库单收获完毕
        AsnDetailCriteria criteria = new AsnDetailCriteria();
        criteria.setBillNo(asnDetail.getBillNo());
        List<AsnDetailDto> asnDetails = asnDetailService.findList(criteria);
        Boolean asnAccept = true;
        AsnMaster asnMaster = asnMasterService.findBy("bill_no", asnDetail.getBillNo());
        for (AsnDetail ad : asnDetails) {
            if (ObjectUtil.notEqual(AsnManageConstant.ASN_STATE_ALL, ad.getState())) {
                asnAccept = false;
                break;
            }
        }
        if (asnAccept) {
            asnMaster.setAsnState(AsnManageConstant.ASN_STATE_ALL);
        } else {
            asnMaster.setAsnState(AsnManageConstant.ASN_STATE_PARTED);
        }
        asnMasterService.updateById(asnMaster);
        //TODO:更新采购单信息
//        updatePOState(acceptInsert, asnDetail, acceptRecord);
    }

    private void updateBatchASNState(List<AcceptRecord > acceptRecords) {
        List<String> asnDetailNos = acceptRecords.stream().map(item -> item.getAsnDetailNo()).collect(Collectors.toList());
        List<AsnDetail> asnDetailList = asnDetailService.list(new QueryWrapper<AsnDetail>().in("detail_no", asnDetailNos));//更新ASN明细
        Map<String, AsnDetail> asnDetailMap = convertMap(asnDetailList, AsnDetail::getDetailNo);
        for (AcceptRecord acceptRecord : acceptRecords) {
            AsnDetail asnDetail = asnDetailMap.get(acceptRecord.getAsnDetailNo());
            asnDetail.setAcceptQuantity(acceptRecord.getQuantity() + asnDetail.getAcceptQuantity());
            asnDetail.setAcceptTime(acceptRecord.getAcceptTime());
            if (asnDetail.getAcceptQuantity().equals(asnDetail.getExpectQuantity())) {
                asnDetail.setState(AsnManageConstant.ASN_STATE_ALL);
            } else {
                asnDetail.setState(AsnManageConstant.ASN_STATE_PARTED);
            }
            if (acceptRecord.getQuantity() > asnDetail.getExpectQuantity()) {
                asnDetail.setState(AsnManageConstant.ASN_STATE_OVER);
            }
        }
        asnDetailService.updateBatchById(asnDetailList);


        //异步修改单据状态
        CompletableFuture.runAsync(() -> {
            updateState(asnDetailList.listIterator().next().getBillNo());
        });
    }


    private void updateState(String billNo) {
        List<AsnDetail> asnDetails = asnDetailService.list(new QueryWrapper<AsnDetail>().eq("bill_no", billNo));
        AsnMaster asnMaster = asnMasterService.findBy("bill_no", billNo);
        Boolean asnAccept = true;
        for (AsnDetail ad : asnDetails) {
            if (ObjectUtil.notEqual(AsnManageConstant.ASN_STATE_ALL, ad.getState())) {
                asnAccept = false;
                break;
            }
        }
        if (asnAccept) {
            asnMaster.setAsnState(AsnManageConstant.ASN_STATE_ALL);
        } else {
            asnMaster.setAsnState(AsnManageConstant.ASN_STATE_PARTED);
        }
        asnMasterService.updateById(asnMaster);

    }
    /**
     * 更新采购单状态
     *
     * @param acceptInsert AcceptInsert
     * @param asnDetail    入库单明细
     * @param acceptRecord 收货记录
     */
    private void updatePOState(AcceptInsert acceptInsert, AsnDetail asnDetail, AcceptRecord acceptRecord) {
        if (acceptInsert.getRequestDetailDetailNo() != null) {
            RequestBuyDetail requestBuyDetail = requestBuyDetailService.findByDetailNo(asnDetail.getRequestDetailDetailNo());
            requestBuyDetail.setAcceptQuantity(acceptRecord.getQuantity() + requestBuyDetail.getAcceptQuantity());
            requestBuyDetail.setAcceptTime(acceptInsert.getAcceptTime());
            if (acceptRecord.getQuantity().equals(requestBuyDetail.getExpectQuantity())) {
                requestBuyDetail.setState(AsnManageConstant.ASN_STATE_ALL);
            } else {
                requestBuyDetail.setState(AsnManageConstant.ASN_STATE_PARTED);
            }
            if (acceptRecord.getQuantity() > (requestBuyDetail.getExpectQuantity())) {
                requestBuyDetail.setState(AsnManageConstant.ASN_STATE_OVER);
            }
            requestBuyDetailService.updateById(requestBuyDetail);

            //根据detail的收货状态判断 master的采购收货状态
            RequestBuyDetailCriteria criteria1 = new RequestBuyDetailCriteria();
            criteria1.setBillNo(requestBuyDetail.getBillNo());
            List<RequestBuyDetailDto> requestBuyDetails = requestBuyDetailService.findList(criteria1);

            Boolean requestAccept = true;
            RequestBuy requestBuy = requestBuyService.findBy("bill_no", requestBuyDetail.getBillNo());
            for (RequestBuyDetail requestBuyDetail1 : requestBuyDetails) {
                if (requestBuyDetail1.getState() != 3) {
                    requestAccept = false;
                }
                if (acceptRecord.getQuantity() > (requestBuyDetail1.getExpectQuantity())) {
                    requestBuyDetail.setState(AsnManageConstant.ASN_STATE_OVER);
                }
                if (acceptRecord.getQuantity() < (requestBuyDetail1.getExpectQuantity())) {
                    requestBuy.setAcceptState(AsnManageConstant.ASN_STATE_PARTED);
                }
                requestBuyService.updateById(requestBuy);
            }
            if (requestAccept) {
                requestBuy.setAcceptState(AsnManageConstant.ASN_STATE_ALL);
                requestBuyService.updateById(requestBuy);
            }
        }
    }

    /**
     * 获取物料对应的质检策略
     *
     * @param itemCode 物料编码
     * @return String
     */
    private String getQcTacticCode(String itemCode) {
//        Integer organizationId = acceptInsert.getOrganizationId();
        ItemInfo itemInfo = itemInfoService.findBy("item_code", itemCode);
        String qcTacticCode = itemInfo.getQcTacticCode();
//        if (StringUtils.isNotEmpty(itemInfo.getQcTacticCode())) {
//            qcTacticCode = itemInfo.getQcTacticCode();
//        } else {
//            Organization organization = organizationService.getById(organizationId);
//            if (organization != null && StringUtils.isNotEmpty(organization.getQcTacticCode())) {
//                qcTacticCode = organization.getQcTacticCode();
//            }
//        }
        return qcTacticCode;
    }

    @Override
    public List<AcceptRecord> findDayList(AcceptRecordCriteria criteria) {
        return acceptRecordMapper.findDayList(criteria);
    }

    @Override
    public List<AcceptRecord> findCanTongbu() {
        return acceptRecordMapper.findCanTongbu();
    }

    @Override
    public List<AcceptRecord> saveAndConfirmAcceptRecord(List<AcceptInsert> acceptInserts) {
        List<AcceptRecord> acceptRecords = this.createAcceptRecord(acceptInserts);
        return this.confirmAcceptRecord(acceptRecords);
    }

    @Override
    public List<AcceptRecord> createAcceptRecord(List<AcceptInsert> acceptInserts) {
        List<AcceptRecord> list = new ArrayList<>();
        for (AcceptInsert acceptInsert : acceptInserts) {
            //Step1.各类数据数据校验，不合法给与异常信息提示
            //仓库  货主 库位 容器  物料
            this.validateAndPrepareAcceptData(acceptInsert);
            //Step2.组装收货单数据
            AcceptRecord acceptRecord = new AcceptRecord();
            BeanUtils.copyProperties(acceptInsert, acceptRecord);
            //履约号
            acceptRecord.setAgreementNo(acceptInsert.getAgreementNo());
            //默认质检数量为0
            acceptRecord.setQcQuantity(0.00D);
            //收货单号
            acceptRecord.setAcceptRecordCode(codeRuleService.generateCodeByRedis(SystemManageConstant.CODE_RULE_AC));
            //收货库位
            acceptRecord.setCellCode(acceptInsert.getToCellCode());
            //收货容器
            acceptRecord.setBoxCode(acceptInsert.getToBoxCode());
            // 收货数量
            acceptRecord.setQuantity(acceptInsert.getToQuantity());
            // 已装箱数量
            acceptRecord.setPackedQuantity(0.0);
            //包装及转换率
            acceptRecord.setPackDetailId(acceptInsert.getToPackDetailId());
            acceptRecord.setPackDescribe(acceptInsert.getToPackDescribe());
            acceptRecord.setTransRatio(acceptInsert.getToTransRatio());
            //单据类型? 是否需要

            //收货单状态-默认0 新建
            acceptRecord.setState(AsnManageConstant.ACCEPT_STATE_INIT);
            //质检状态 0免检 1待检 2已检

            //收货日期
            acceptRecord.setAcceptTime(DateUtil.now());

            //如高项目代码
            // 规格
            acceptRecord.setModel(acceptInsert.getModel());
            // 执行版本                                             getQualifiedQuantity
            acceptRecord.setVersion(acceptInsert.getVersion());
            // 现行版本
            acceptRecord.setLatestVersion(acceptInsert.getLatestVersion());
            acceptRecord.setBatchName(acceptInsert.getBatchName());
            acceptRecord.setAsnStockId(acceptInsert.getAsnStockId());
            acceptRecord.setAsnStockName(acceptInsert.getAsnStockName());
            acceptRecord.setCategoryId(acceptInsert.getCategoryId());
            //Step3.保存
            acceptRecordService.save(acceptRecord);
            list.add(acceptRecord);
        }
        return list;
    }

    @Override
    public List<AcceptRecord> confirmAcceptRecord(List<AcceptRecord> acceptRecords) {
        for (AcceptRecord acceptRecord : acceptRecords) {
            //Step1.判断收货单是否满足确认的条件 修改状态
            if (ObjectUtil.notEqual(AsnManageConstant.ACCEPT_STATE_INIT, acceptRecord.getState())) {
                throw new ServiceException(CommonCode.SERVER_INERNAL_ERROR, "收货单不为新建状态，不可确认!");
            }
            AsnMaster asnMaster = asnMasterService.getOne(new QueryWrapper<AsnMaster>().eq("bill_no", acceptRecord.getAsnBillNo()));
            if (ObjectUtil.isNotEmpty(asnMaster.getBillType()) && 702 == asnMaster.getBillType() && asnMaster.getNotQc() != 1) {
                acceptRecord.setQcState(1);

            } else {
                acceptRecord.setQualifiedQuantity(acceptRecord.getQuantity());
                acceptRecord.setUnqualifiedQuantity(0.0);
                acceptRecord.setQcState(0);
            }
            acceptRecord.setState(AsnManageConstant.ACCEPT_STATE_CONFIRMED);

            //Step2.生成库存事务请求 并提交
            InventoryTransact inventoryTransact = this.toStockRequest(acceptRecord);
            int inventoryId = inventoryTransactService.run(inventoryTransact);
            acceptRecord.setInventoryId(inventoryId);
            acceptRecordService.updateById(acceptRecord);

            //Step3. 回写上游单据[入库任务]状态
            //要判断是否需要回写
            if (StringUtils.isNotEmpty(acceptRecord.getAsnDetailNo())) {
                this.updateASNState(acceptRecord);
            }
        }
        return acceptRecords;
    }


    /**
     * 根据收货单生成库存事务
     *
     * @param acceptRecord
     * @return
     */
    public InventoryTransact toStockRequest(AcceptRecord acceptRecord) {
        InventoryTransact inventoryTransact = new InventoryTransact();
        //Step1.准备数据
        //仓库
        inventoryTransact.setWareId(acceptRecord.getWareId());
        inventoryTransact.setWareName(acceptRecord.getWareName());
        //货主
        inventoryTransact.setToOrganizationId(acceptRecord.getOrganizationId());
        inventoryTransact.setToOrganizationName(acceptRecord.getOrganizationName());
        //库位
        inventoryTransact.setToCellCode(acceptRecord.getCellCode());
        //容器
        inventoryTransact.setToBoxCode(acceptRecord.getBoxCode());
        //物料
        inventoryTransact.setItemCode(acceptRecord.getItemCode());
        inventoryTransact.setItemName(acceptRecord.getItemName());
        inventoryTransact.setSpec(acceptRecord.getSpec());
        inventoryTransact.setModel(acceptRecord.getModel());
        inventoryTransact.setImgUrl(acceptRecord.getImgUrl());
        //批次
        inventoryTransact.setToBatchId(acceptRecord.getBatchId());
        inventoryTransact.setToBatchName(acceptRecord.getBatchName());
        //数量
        inventoryTransact.setToQuantity(acceptRecord.getQuantity());
        //包装 转换率
        inventoryTransact.setToPackDetailId(acceptRecord.getPackDetailId());
        inventoryTransact.setToPackDescribe(acceptRecord.getPackDescribe());
        inventoryTransact.setToTransRatio(acceptRecord.getTransRatio());
        //创建人 时间
        inventoryTransact.setCreateUserId(acceptRecord.getAcceptUserId());
        inventoryTransact.setCreateUserName(acceptRecord.getAcceptUserName());
        inventoryTransact.setCreateTime(acceptRecord.getAcceptTime());
        //事务类型
        inventoryTransact.setTransactType(handleTransactType(acceptRecord));
        //来源单据号
        inventoryTransact.setBillNo(acceptRecord.getAsnBillNo());
        inventoryTransact.setAsnStockId(acceptRecord.getAsnStockId());
        inventoryTransact.setAsnStockName(acceptRecord.getAsnStockName());
        inventoryTransact.setFromBatchName(acceptRecord.getBatchName());
        inventoryTransact.setAgreementNo(acceptRecord.getAgreementNo());
        //单号
        inventoryTransact.setBillNo(acceptRecord.getAsnBillNo());
        //明细行
        inventoryTransact.setDetailNo(acceptRecord.getAsnDetailNo());
        inventoryTransact.setMtoNo(acceptRecord.getMtoNo());
        inventoryTransact.setCategoryId(acceptRecord.getCategoryId());


        //质检标识
        if (ObjectUtil.notEqual(AsnManageConstant.ACCEPT_QC_STATE_EXEMPTION, acceptRecord.getQcState())) {
            //需要质检
            inventoryTransact.setState(InventoryConstant.TRANSACT_STATE_UNNORMAL);
            inventoryTransact.setStateDis("未质检");
        } else {
            inventoryTransact.setState(InventoryConstant.TRANSACT_STATE_NORMAL);
        }

        //Step2.保存，返回
        inventoryTransactService.save(inventoryTransact);
        return inventoryTransact;
    }

    private Integer handleTransactType(AcceptRecord acceptRecord) {
        if (StringUtils.isEmpty(acceptRecord.getAsnBillNo())) {
            //没有来源单据，盲收
            return InventoryConstant.TRANSACT_TYPE_BLIND;
        }
        if (StringUtils.isEmpty(acceptRecord.getBoxCode())) {
            //没有目标容器  到货暂收
            return InventoryConstant.TRANSACT_TYPE_ASN;
        }
        //有目标容器  收货即装箱
        return InventoryConstant.TRANSACT_TYPE_ACCEPT;
    }

    @Autowired
    private QcRecordService qcRecordService;

    @Override
    public String billToErpNew(String billNo, QcRecord qcRecord) {
        QueryWrapper<AsnMaster> amqw = Wrappers.query();
        AsnMaster asnMaster = asnMasterMapper.selectOne(amqw.eq("bill_no", billNo));
        QcOrderToErpBO bo = new QcOrderToErpBO();
        QueryWrapper<AsnDetail> adqw = Wrappers.query();
        AsnDetail asnDetail = asnDetailMapper.selectOne(adqw.eq("detail_no", qcRecord.getQcBillNo()));
        bo.setBillTypeId(711);
        bo.setBillNo(codeRuleService.generateCodeByRedis("QC"));
        bo.setBillDate(DateUtils.getNowDateString());
        bo.setSourceBillTypeId(asnMaster.getBillType());
        bo.setRemark(asnMaster.getMemo());
        bo.setSourceBillId(asnMaster.getBeforeNum());
        bo.setSourceBillDetailRowIndex(asnDetail.getRowIndex());
        //合格数量+让步数量
        bo.setQualifiedQty(qcRecord.getQualifiedQuantity() + qcRecord.getConcessionQuantity());
        bo.setConcessionAcceptId(qcRecord.getConcessionAcceptId());
        bo.setQualityAbnormalId(qcRecord.getQualityAbnormalId());
        bo.setQty(qcRecord.getQcQuantity());//checkQuantity已检数量
        Double totalQty =  qcRecord.getQualifiedQuantity() + qcRecord.getConcessionQuantity();
        bo.setInspectionMethodId(353);
        bo.setInspectionResultId(qcRecord.getFiedQuantity()>0 ?  287:286 );
        String s = pushErpService.pushQCBIll(bo);
        qcRecord.setAuditId(s);
        qcRecordService.updateById(qcRecord);
        //下推不合格数量
        if (ObjectUtil.isNotEmpty(qcRecord.getFiedQuantity())) {
            CompletableFuture.runAsync(() -> {
                try {
                    acceptRecordService.checkBillToErp(s);
                    bo.setBillTypeId(73);
                    bo.setBillNo(codeRuleService.generateCodeByRedis("NOTQC"));
                    bo.setQty(qcRecord.getQcQuantity() - qcRecord.getQualifiedQuantity() - qcRecord.getConcessionQuantity());
                    if (ObjectUtil.isNotEmpty(bo.getQty())) {
                        bo.setQualifiedQty(null);
                        pushErpService.PushPOReceivingReturn(bo);
                    }
                    qcRecordService.updateById(qcRecord);
                } catch (Exception e) {
                    System.out.println(e.getMessage());
                }
            });
        }
        return s;

    }

    @Override
    public void updateQcState(String acceptRecordCode, int qcState) {
        acceptRecordMapper.updateQcState(acceptRecordCode, qcState);
    }

    @Override
    public void updateAllQcState(String asnBillNo, int qcState) {
        acceptRecordMapper.updateAllQcState(asnBillNo, qcState);
    }

    @Override
    public List<AcceptRecord> findBillNo(String toBoxCode) {
        return acceptRecordMapper.findBillNo(toBoxCode);
    }


    @Override
    //审核回传异步处理
    //不影响线程正常流程,错误信息在日志记录

    public void checkBillToErp(String billId) {
        Map<String, Object> cbMap = new HashMap();
        cbMap.put("billTypeId", 711);
        cbMap.put("billId", Integer.parseInt(billId));
        try {
            pushErpService.CheckBill(cbMap);
        } catch (Exception e) {
            log.info("{}\n<<<<-ERP审核报错\n>>>>", JSON.toJSONString(cbMap));
        }
    }


    /**
     * 容器编码找类型
     *
     * @param code
     * @return
     */
    @Override
    public Map<String, Object> finbyCode(String code) {
        return acceptRecordMapper.findByCode(code);
    }

    @Override
    public void StraightHairEmptyWarehouse(AsnMaster asnMaster, CurrentUser currentUser) {
        if (currentUser == null) {
            currentUser = new CurrentUser();
            currentUser.setUserId(1);
            currentUser.setUserName("超级管理员");
        }
        //1.封装收货单数据
        List<AcceptRecord> list = new ArrayList<AcceptRecord>();
        // 根据入库任务单号查询明细信息
        List<AsnDetail> details = asnDetailService.findByBillNo(asnMaster.getBillNo());
        for (AsnDetail detail : details) {
            AcceptRecord acceptRecord = new AcceptRecord();
            //收货单号
            acceptRecord.setAcceptRecordCode(codeRuleService.generateCodeByRedis(SystemManageConstant.CODE_RULE_AC));
            // 仓库、货主和物料信息
            acceptRecord.setWareId(asnMaster.getWareId());
            acceptRecord.setWareName(asnMaster.getWareName());
            acceptRecord.setOrganizationId(asnMaster.getOrganizationId());
            acceptRecord.setOrganizationName(asnMaster.getOrganizationName());
            acceptRecord.setItemCode(detail.getItemCode());
            acceptRecord.setItemName(detail.getItemName());
//            acceptRecord.setSpec(detail.getSpec());
            //包装及转换率
            if (detail.getPackDetailId() == null || detail.getPackDescribe() == null) {
                //33469 件
                acceptRecord.setPackDetailId(33469);
                acceptRecord.setPackDescribe("件");
            } else {
                acceptRecord.setPackDetailId(detail.getPackDetailId());
                acceptRecord.setPackDescribe(detail.getPackDescribe());
            }
//            acceptRecord.setTransRatio(detail.getTransRatio());
            //收货数量
            acceptRecord.setExpectQuantity(detail.getExpectQuantity());
            acceptRecord.setQuantity(detail.getExpectQuantity());
            // 无目标容器和库位
            acceptRecord.setBillType(0);
            acceptRecord.setAsnBillNo(asnMaster.getBillNo());
            acceptRecord.setAsnDetailNo(detail.getDetailNo());
            //2.操作人员信息
            Integer userId = currentUser.getUserId();
            String userName = currentUser.getUserName();
            String acceptTime = DateUtils.getNowDateTimeString();
            acceptRecord.setAcceptUserId(userId);
            acceptRecord.setAcceptUserName(userName);
            acceptRecord.setAcceptTime(acceptTime);
            // 批次信息
            Map<String, Object> map = new HashMap<>();
            map.put("detail_no", acceptRecord.getAsnBillNo());
            map.put("in_date", DateUtil.today());
            ItemBatch itemBatch = itemBatchService.getOneByMap(map);
            if (ObjectUtil.isNull(itemBatch)) {
                itemBatch = itemBatchService.createSimpleItemBatch(acceptRecord.getAsnBillNo());
            }
            acceptRecord.setBatchId(itemBatch.getBatchId());
            acceptRecord.setBatchName(itemBatch.getBatchName());
            // 收货单状态-2已确认
            acceptRecord.setState(AsnManageConstant.ACCEPT_STATE_CONFIRMED);
            // 质检状态 0免检
            acceptRecord.setQcState(AsnManageConstant.ACCEPT_QC_STATE_EXEMPTION);
            // 收货日期
            acceptRecord.setAcceptTime(DateUtil.now());

            // 3.新增收货单
            acceptRecordService.save(acceptRecord);

            //4.修改入库任务明细的状态
            // 设置入库明细的验收数量
            detail.setAcceptQuantity(detail.getExpectQuantity());
            // 物料直接是合格的
            detail.setQcState(1);
            // 状态为全部收货
            detail.setState(3);
            // 修改信息
            asnDetailService.saveOrUpdate(detail);
            list.add(acceptRecord);
        }
        //5.修改入库任务的状态
        //  ASN状态  0-初始化 1-已码盘  2-部分收货  3-全部收货  4-ASN完成  5-超额收货
        asnMaster.setAsnState(3);
        asnMaster.setQcState(1);
        asnMasterService.saveOrUpdate(asnMaster);

        // 创建出库任务 履约号-soUdfHs2
        SoMaster soMaster = new SoMaster();
        /**
         *  新建SO单据
         */

        String tableName = "so_master";
        Integer nextId = validatorService.getNextId(tableName);

        String billNo = "SO" + "-" + nextId;
        Integer createUserId = currentUser.getUserId();
        String createUserName = currentUser.getUserName();
        String createTime = DateUtils.getNowDateTimeString();
        soMaster.setCreateUserId(createUserId);
        soMaster.setCreateUserName(createUserName);
        soMaster.setCreateTime(createTime);
        // 出库单号
        soMaster.setBillNo(billNo);
        // 状态 8-完全发运
        soMaster.setState(8);
        // 仓库信息
        soMaster.setWareId(asnMaster.getWareId());
        soMaster.setWareCode(asnMaster.getWareCode());
        soMaster.setWareName(asnMaster.getWareName());
        // 货主信息
        soMaster.setOrganizationId(asnMaster.getOrganizationId());
        soMaster.setOrganizationName(asnMaster.getOrganizationName());
        soMaster.setOrganizationCode(asnMaster.getOrganizationCode());

        // 时间信息
        soMaster.setOrderTime(DateUtil.now());
        soMaster.setDeliveryTime(DateUtils.getNowDateTimeString());
        soMaster.setExpectTimeFm(DateUtils.getNowDateTimeString());
        soMaster.setExpectTimeTo(DateUtils.getNowDateTimeString());
        soMaster.setBillSource(1);
        //履约号-soUdfHs2
        soMaster.setSoUdfHs2(asnMaster.getUda1());
        // 明细行数
        soMaster.setSoStructure(details.size());
        // 审核状态不需要
        // 客户信息--还是领料部门和领料人--先不填写
        // 保存信息
        soMasterService.save(soMaster);
        // 明细信息
        for (int i = 0; i < details.size(); i++) {
            SoDetail soDetail = new SoDetail();
            AsnDetail detail = details.get(i);
            // 出库任务单号
            soDetail.setBillNo(soMaster.getBillNo());
            String detailNo = soMaster.getBillNo() + "-" + (i + 1);
            // 详情单号
            soDetail.setDetailNo(detailNo);
            // 状态--全部拣货
            soDetail.setState(4);
            // 物料信息
            soDetail.setItemCode(detail.getItemCode());
            soDetail.setItemName(detail.getItemName());
            soDetail.setSpec(detail.getSpec());
            // 数量--订货数，发货数量
            soDetail.setOrderQuantity(detail.getExpectQuantity());
            soDetail.setDeliveryQuantity(detail.getExpectQuantity());
            soDetail.setAllottedQuantity(detail.getExpectQuantity());
            soDetail.setPickQuantity(detail.getExpectQuantity());
            // 设置转换率
            if (detail.getTransRatio() != null) {
                soDetail.setTransRatio(detail.getTransRatio());
            } else {
                soDetail.setTransRatio(1.0);
            }

            // 履约号-soUdfHs2
            soDetail.setSoUdfDs2(detail.getUda1());
            soDetailService.save(soDetail);
        }
        // 回传erp--是否需要
//        soMasterService.outbillToErpNew(billNo);
    }

    @Override
    public void createByAsnDetail(AsnMaster asnMaster, String cellCode, CurrentUser currentUser) {
        List<AcceptInsert> acceptInserts = new ArrayList<>();
        List<AsnDetail> asnDetails = asnDetailService.findByBillNo(asnMaster.getBillNo());
        for (AsnDetail detail : asnDetails) {
            AcceptInsert acceptInsert = new AcceptInsert();
            acceptInsert.setWareId(asnMaster.getWareId());
            acceptInsert.setWareName(asnMaster.getWareName());
            acceptInsert.setItemName(detail.getItemName());
            acceptInsert.setItemCode(detail.getItemCode());
            acceptInsert.setBatchName(asnMaster.getAgreementNo());
            acceptInsert.setToPackDetailId(detail.getPackDetailId());
            acceptInsert.setToPackDescribe(detail.getPackDescribe());
            acceptInsert.setToTransRatio(detail.getTransRatio());
            acceptInsert.setToQuantity(detail.getExpectQuantity());
            acceptInsert.setToCellCode(cellCode);
            acceptInsert.setAcceptUserId(currentUser.getUserId());
            acceptInsert.setAcceptUserName(currentUser.getUserName());
            acceptInsert.setAcceptTime(DateUtil.now());
            acceptInsert.setBillType(0);
            acceptInsert.setAsnDetailNo(detail.getDetailNo());
            acceptInsert.setAsnBillNo(detail.getBillNo());
            // 质检-0
            acceptInsert.setQcState(0);
            acceptInserts.add(acceptInsert);
        }
        //Step1.创建收货单并确认
        this.saveAndConfirmAcceptRecord(acceptInserts);

    }


    /**
     * 产品入库接口回传数据
     */
    @Override
    public void toERP(String cellCode, AsnMaster asnMaster) {
        OrderToErpBO pushErpBean = getPushErpBean(asnMaster.getBillNo(), cellCode);
        // 拉取的单子回传
        pushErpService.pushIMBIll(pushErpBean);
    }

    @Autowired
    private InventoryService inventoryService;


    @Override
    public void saveBathInv() {
        List<AcceptRecord> list = acceptRecordService.list();
        for (AcceptRecord acceptRecord : list) {
            Integer inventoryId = acceptRecord.getInventoryId();
            Inventory inventory = inventoryService.getById(inventoryId);
            if (ObjectUtil.isNotEmpty(inventory)) {
                inventory.setAsnBillNo(acceptRecord.getAsnBillNo());
                inventory.setAsnDetailNo(acceptRecord.getAsnDetailNo());
                inventoryService.updateById(inventory);
            }
        }

    }

    @Autowired
    private PickTaskService pickTaskService;

    @Override
    public void pdaBatchAccept(AsnMaster asnMaster, CurrentUser currentUser) {
        if (ObjectUtil.isEmpty(asnMaster.getAsnType())) {
            return;
        }
        if (ObjectUtil.isEmpty(asnMaster.getId())) {
            if (ObjectUtil.isEmpty(asnMaster.getBillType()) || ObjectUtil.isEmpty(asnMaster.getBeforeNum())) {
                log.error("审核异常单子{}", JSON.toJSONString(asnMaster));
            }
            Map<String, Object> cbMap = new HashMap();
            cbMap.put("billTypeId", asnMaster.getBillType());
            cbMap.put("billId", asnMaster.getBeforeNum());
            CompletableFuture.runAsync(() -> {
                pushErpService.CheckBill(cbMap);
            });
            List<AsnDetail> asnDetails = asnMaster.getAsnDetails();
            asnMasterService.saveOrUpdate(asnMaster);
            asnDetailService.saveOrUpdateBatch(asnDetails);
        }
        if (ObjectUtil.isNull(currentUser)) {
            return;
        }
        List<AsnDetail> asnDetails = asnDetailService.findByBillNo(asnMaster.getBillNo());
        for (AsnDetail asnDetail : asnDetails) {
            if (Double.doubleToLongBits(asnDetail.getExpectQuantity()) == Double.doubleToLongBits(asnDetail.getAcceptQuantity())) {
                continue;
            }
            AcceptInsert accept = new AcceptInsert();
            accept.setOrganizationId(asnMaster.getOrganizationId());
            if (asnMaster.getAsnType() == 41) {
                InventorySelectDto inv = inventoryService.findbyInv(asnDetail.getAllotDetailNo());
            if (ObjectUtil.isNotEmpty(inv)) {
                    accept.setBatchName(inv.getBatchName());
                    accept.setAgreementNo(inv.getAgreementNo());
                    accept.setMtoNo(inv.getMtoNo());
                }
            }
            String sysAcceptCell = cellInfoService.getSysAcceptCell(asnMaster.getWareId());
            accept.setToCellCode(sysAcceptCell);
            accept.setWareId(asnMaster.getWareId());
            accept.setWareName(asnMaster.getWareName());
            accept.setAsnBillNo(asnDetail.getBillNo());
            accept.setAsnDetailNo(asnDetail.getDetailNo());
            accept.setItemCode(asnDetail.getItemCode());
            accept.setToQuantity(asnDetail.getExpectQuantity() - asnDetail.getAcceptQuantity());
            accept.setAcceptUserId(currentUser.getUserId());
            accept.setAcceptUserName(currentUser.getUserName());
            accept.setToPackDetailId(asnDetail.getPackDetailId());
            accept.setToPackDescribe(asnDetail.getPackDescribe());
            accept.setItemName(asnDetail.getItemName());
            accept.setAsnStockId(asnDetail.getStockId());
            accept.setAsnStockName(asnDetail.getStockName());
            // 规格
            accept.setModel(asnDetail.getUda1());
            // 执行版本
            accept.setVersion(asnDetail.getVersion());
            // 现行版本
            accept.setLatestVersion(asnDetail.getLatestVersion());
            acceptRecordService.accept(accept);
        }

    }

    public void pdaAccept(AsnMaster asnMaster, CurrentUser currentUser) {
        if (ObjectUtil.isEmpty(asnMaster.getAsnType())) {
            return;
        }
        if (ObjectUtil.isNull(currentUser)) {
            return;
        }


        if (ObjectUtil.isEmpty(asnMaster.getId())) {
            if (ObjectUtil.isEmpty(asnMaster.getBillType()) || ObjectUtil.isEmpty(asnMaster.getBeforeNum())) {
                log.error("审核异常单子{}", JSON.toJSONString(asnMaster));
            }
            Map<String, Object> cbMap = new HashMap();
            cbMap.put("billTypeId", asnMaster.getBillType());
            cbMap.put("billId", asnMaster.getBeforeNum());
            //异步审核
            CompletableFuture.runAsync(() -> {
                pushErpService.CheckBill(cbMap);
            });
            List<AsnDetail> asnDetails = asnMaster.getAsnDetails();
            asnMasterService.saveOrUpdate(asnMaster);
            asnDetailService.saveOrUpdateBatch(asnDetails);
        }
        List<AsnDetail> asnDetails = asnDetailService.list(new QueryWrapper<AsnDetail>().eq("bill_no", asnMaster.getBillNo()));
        List<AcceptInsert> acceptInserts = new ArrayList<>();

        for (AsnDetail asnDetail : asnDetails) {
            if (Double.doubleToLongBits(asnDetail.getExpectQuantity()) == Double.doubleToLongBits(asnDetail.getAcceptQuantity())) {
                continue;
            }
            AcceptInsert accept = new AcceptInsert();
            accept.setOrganizationId(asnMaster.getOrganizationId());
            if (asnMaster.getAsnType() == 41) {
                InventorySelectDto inv = inventoryService.findbyInv(asnDetail.getAllotDetailNo());
                if (ObjectUtil.isNotEmpty(inv)) {
                    accept.setBatchName(inv.getBatchName());
                    accept.setAgreementNo(inv.getAgreementNo());
                    accept.setMtoNo(inv.getMtoNo());
                }
            }
            String sysAcceptCell = cellInfoService.getSysAcceptCell(asnMaster.getWareId());
            accept.setToCellCode(sysAcceptCell);
            accept.setWareId(asnMaster.getWareId());

            accept.setWareName(asnMaster.getWareName());
            accept.setAsnBillNo(asnDetail.getBillNo());
            accept.setAsnDetailNo(asnDetail.getDetailNo());
            accept.setItemCode(asnDetail.getItemCode());
            accept.setToQuantity(asnDetail.getExpectQuantity() - asnDetail.getAcceptQuantity());
            accept.setAcceptUserId(currentUser.getUserId());
            accept.setAcceptUserName(currentUser.getUserName());
            accept.setToPackDetailId(asnDetail.getPackDetailId());
            accept.setToPackDescribe(asnDetail.getPackDescribe());
            accept.setItemName(asnDetail.getItemName());
            accept.setAsnStockId(asnDetail.getStockId());
            accept.setAsnStockName(asnDetail.getStockName());
            // 规格
            accept.setModel(asnDetail.getUda1());
            // 执行版本
            accept.setVersion(asnDetail.getVersion());
            // 现行版本
            accept.setLatestVersion(asnDetail.getLatestVersion());
            acceptInserts.add(accept);
//            acceptRecordService.accept(accept);
        }
        acceptRecordService.batchAccept(acceptInserts);
    }

    @Override
    public long findCount(AcceptRecordCriteria criteria) {
        return baseMapper.findCount(criteria);

    }

    /**
     * 合格未入库
     *
     * @param criteria
     * @return
     */
    @Override
    public List<AcceptRecordExcel> notPut(AcceptRecordCriteria criteria) {
        List<AcceptRecordExcel> acceptRecordExcels = baseMapper.notPut(criteria);
        List<String> billNos = acceptRecordExcels.stream().map(item -> item.getAsnBillNo()).collect(Collectors.toList());
        List<AsnMaster> asnMasters = asnMasterService.list(new QueryWrapper<AsnMaster>().in("bill_no", billNos));
        Map<String, AsnMaster> asnMasterMap = convertMap(asnMasters, AsnMaster::getBillNo);
        List<AsnDetail> asnDetails = asnDetailService.list(new QueryWrapper<AsnDetail>().in("bill_no", billNos));
        Map<String, AsnDetail> detailMap = convertMap(asnDetails, AsnDetail::getDetailNo);


        Set<String> itemCodes = acceptRecordExcels.stream().map(AcceptRecordExcel::getItemCode).collect(Collectors.toSet());
        List<AcceptRecordExcel> upExcels =   acceptRecordService.findLast(itemCodes);
        Map<String, AcceptRecordExcel> acceptRecordExcelMap = convertMap(upExcels, AcceptRecordExcel::getItemCode);
        for (AcceptRecordExcel accept : acceptRecordExcels) {
            AcceptRecordExcel newAccept = acceptRecordExcelMap.get(accept.getItemCode());
            AsnMaster asnMaster = asnMasterMap.get(accept.getAsnBillNo());
            AsnDetail asnDetail = detailMap.get(accept.getAsnDetailNo());
            if (ObjectUtil.isNotEmpty(asnMaster)) {
                accept.setSupplierName(asnMaster.getSupplierName());
            }
            if (ObjectUtil.isNotEmpty(asnDetail)) {
                accept.setMemo(asnDetail.getMemo());
            }
            if (ObjectUtil.isNotEmpty(newAccept)) {
            accept.setConfirmUserName(newAccept.getConfirmUserName());
            accept.setToCellCode(newAccept.getToCellCode());
            }
        }
        return acceptRecordExcels;
    }

    @Override
    public List<AcceptRecordExcel> findLast(Set<String> itemCodes) {
    return     baseMapper.findLast(itemCodes);
    }

    /**
     * 批量到货暂收
     *
     * @param acceptInserts
     */
    @Override
    public void batchAccept(List<AcceptInsert> acceptInserts) {
        List<AcceptRecord> acceptRecords = new ArrayList<>();
        List<InventoryTransact> inventoryTransacts = new ArrayList<>();
        if (ObjectUtil.isEmpty(acceptInserts)) {
            return;
        }
        for (AcceptInsert acceptInsert : acceptInserts) {
            QueryWrapper<ItemBatch> queryWrapper = new QueryWrapper();
            queryWrapper.eq("detail_no", acceptInsert.getAsnBillNo());
            queryWrapper.eq("in_date", DateUtil.today());
            queryWrapper.last("limit 1");
            ItemBatch itemBatch = itemBatchService.getOne(queryWrapper);
            if (ObjectUtil.isEmpty(itemBatch)) {
                itemBatch = itemBatchService.createSimpleItemBatch(acceptInsert.getAsnBillNo());
            }
            acceptInsert.setBatchId(itemBatch.getBatchId());
            if (ObjectUtil.isNotEmpty(acceptInsert.getBatchName())) {
                acceptInsert.setBatchName(acceptInsert.getBatchName());
            } else {
                acceptInsert.setBatchName(itemBatch.getBatchName());
            }
            AcceptRecord acceptRecord = new AcceptRecord();
            BeanUtils.copyProperties(acceptInsert, acceptRecord);
            //履约号
            acceptRecord.setAgreementNo(acceptInsert.getAgreementNo());
            //默认质检数量为0
            acceptRecord.setQcQuantity(0.00D);
            //收货单号
            acceptRecord.setAcceptRecordCode(codeRuleService.generateCodeByRedis(SystemManageConstant.CODE_RULE_AC));
            //收货库位
            acceptRecord.setCellCode(acceptInsert.getToCellCode());
            //收货容器
            acceptRecord.setBoxCode(acceptInsert.getToBoxCode());
            // 收货数量
            acceptRecord.setQuantity(acceptInsert.getToQuantity());
            // 已装箱数量
            acceptRecord.setPackedQuantity(0.0);
            //包装及转换率
            acceptRecord.setPackDetailId(acceptInsert.getToPackDetailId());
            acceptRecord.setPackDescribe(acceptInsert.getToPackDescribe());
            acceptRecord.setTransRatio(acceptInsert.getToTransRatio());
            //单据类型? 是否需要

            //收货单状态-默认0 新建
            acceptRecord.setState(AsnManageConstant.ACCEPT_STATE_INIT);
            //质检状态 0免检 1待检 2已检

            //收货日期
            acceptRecord.setAcceptTime(DateUtil.now());

            //如高项目代码
            // 规格
            acceptRecord.setModel(acceptInsert.getModel());
            // 执行版本                                             getQualifiedQuantity
            acceptRecord.setVersion(acceptInsert.getVersion());
            // 现行版本
            acceptRecord.setLatestVersion(acceptInsert.getLatestVersion());
            acceptRecord.setBatchName(acceptInsert.getBatchName());
            acceptRecord.setAsnStockId(acceptInsert.getAsnStockId());
            acceptRecord.setAsnStockName(acceptInsert.getAsnStockName());
            acceptRecord.setCategoryId(acceptInsert.getCategoryId());
            acceptRecords.add(acceptRecord);
        }
        for (AcceptRecord acceptRecord : acceptRecords) {
            if (ObjectUtil.notEqual(AsnManageConstant.ACCEPT_STATE_INIT, acceptRecord.getState())) {
                throw new ServiceException(CommonCode.SERVER_INERNAL_ERROR, "收货单不为新建状态，不可确认!");
            }
            AsnMaster asnMaster = asnMasterService.getOne(new QueryWrapper<AsnMaster>().eq("bill_no", acceptRecord.getAsnBillNo()));
            if (ObjectUtil.isNotEmpty(asnMaster.getBillType()) && 702 == asnMaster.getBillType() && asnMaster.getNotQc() != 1) {
                acceptRecord.setQcState(1);
            } else {
                acceptRecord.setQualifiedQuantity(acceptRecord.getQuantity());
                acceptRecord.setUnqualifiedQuantity(0.0);
                acceptRecord.setQcState(0);
            }
            acceptRecord.setState(AsnManageConstant.ACCEPT_STATE_CONFIRMED);


            //Step2.生成库存事务请求 并提交
            InventoryTransact inventoryTransact = new InventoryTransact();
            //Step1.准备数据
            //仓库
            inventoryTransact.setWareId(acceptRecord.getWareId());
            inventoryTransact.setWareName(acceptRecord.getWareName());
            //货主
            inventoryTransact.setToOrganizationId(acceptRecord.getOrganizationId());
            inventoryTransact.setToOrganizationName(acceptRecord.getOrganizationName());
            //库位
            inventoryTransact.setToCellCode(acceptRecord.getCellCode());
            //容器
            inventoryTransact.setToBoxCode(acceptRecord.getBoxCode());
            //物料
            inventoryTransact.setItemCode(acceptRecord.getItemCode());
            inventoryTransact.setItemName(acceptRecord.getItemName());
            inventoryTransact.setSpec(acceptRecord.getSpec());
            inventoryTransact.setModel(acceptRecord.getModel());
            inventoryTransact.setImgUrl(acceptRecord.getImgUrl());
            //批次
            inventoryTransact.setToBatchId(acceptRecord.getBatchId());
            inventoryTransact.setToBatchName(acceptRecord.getBatchName());
            //数量
            inventoryTransact.setToQuantity(acceptRecord.getQuantity());
            //包装 转换率
            inventoryTransact.setToPackDetailId(acceptRecord.getPackDetailId());
            inventoryTransact.setToPackDescribe(acceptRecord.getPackDescribe());
            inventoryTransact.setToTransRatio(acceptRecord.getTransRatio());
            //创建人 时间
            inventoryTransact.setCreateUserId(acceptRecord.getAcceptUserId());
            inventoryTransact.setCreateUserName(acceptRecord.getAcceptUserName());
            inventoryTransact.setCreateTime(acceptRecord.getAcceptTime());
            //事务类型
            inventoryTransact.setTransactType(handleTransactType(acceptRecord));
            //来源单据号
            inventoryTransact.setBillNo(acceptRecord.getAsnBillNo());
            inventoryTransact.setAsnStockId(acceptRecord.getAsnStockId());
            inventoryTransact.setAsnStockName(acceptRecord.getAsnStockName());
            inventoryTransact.setFromBatchName(acceptRecord.getBatchName());
            inventoryTransact.setAgreementNo(acceptRecord.getAgreementNo());
            //单号
            inventoryTransact.setBillNo(acceptRecord.getAsnBillNo());
            //明细行
            inventoryTransact.setDetailNo(acceptRecord.getAsnDetailNo());
            inventoryTransact.setMtoNo(acceptRecord.getMtoNo());
            inventoryTransact.setCategoryId(acceptRecord.getCategoryId());
            //到货暂收Code
            inventoryTransact.setAcceptRecordCode(acceptRecord.getAcceptRecordCode());
            //质检标识
            if (ObjectUtil.notEqual(AsnManageConstant.ACCEPT_QC_STATE_EXEMPTION, acceptRecord.getQcState())) {
                //需要质检
                inventoryTransact.setState(InventoryConstant.TRANSACT_STATE_UNNORMAL);
                inventoryTransact.setStateDis("未质检");
            } else {
                inventoryTransact.setState(InventoryConstant.TRANSACT_STATE_NORMAL);
            }
            inventoryTransacts.add(inventoryTransact);
        }
        List<Inventory> invList = new ArrayList<>();
        for (InventoryTransact inventoryTransact : inventoryTransacts) {
            Inventory inventory = inventoryTransactService.processInventoryData(inventoryTransact);
            invList.add(inventory);
        }
        //保存库存
        inventoryService.saveBatch(invList);
        Map<String, Inventory> invMap = convertMap(invList, Inventory::getAcceptRecordCode);
        for (AcceptRecord acceptRecord : acceptRecords) {
            Inventory inventory = invMap.get(acceptRecord.getAcceptRecordCode());
            acceptRecord.setInventoryId(inventory.getInventoryId());
        }
        //保存到货暂收
        acceptRecordService.saveBatch(acceptRecords);
        //修改状态
        updateBatchASNState(acceptRecords);
        //异步保存库存事务
        CompletableFuture.runAsync(() -> {
            inventoryTransactService.saveBatch(inventoryTransacts);
        });

    }




    public OrderToErpBO getPushErpBean(String billNo, String cellCode) {
        QueryWrapper<AsnMaster> amqw = Wrappers.query();
        AsnMaster asnMaster = asnMasterMapper.selectOne(amqw.eq("bill_no", billNo));
        OrderToErpBO bo = new OrderToErpBO();
        OrderDetailBO db = new OrderDetailBO();

        List<OrderDetailBO> pd = new ArrayList<>();
        // 批量操作
        List<AsnDetail> asnDetails = asnDetailService.findByBillNo(billNo);

        for (AsnDetail asnDetail : asnDetails) {
            Integer erpAreaId = cellInfoService.findbyCellCode(cellCode);
            db.setSourceBillId(asnMaster.getBeforeNum()); //源单id
            db.setSourceBillDetailRowIndex(asnDetail.getCreateUserId());//行号
            db.setBatchNo(asnMaster.getAgreementNo());//入库批号
            db.setQty(asnDetail.getAcceptQuantity());//数量
            db.setStockId(erpAreaId); //27972 其他入库
                if (ObjectUtil.isEmpty(asnMaster.getBeforeNum())) {
                bo.setRob(true);
                ItemInfo itemInfo = itemInfoService.findBy("item_code", asnDetail.getItemCode());
                db.setItemId(itemInfo.getErpItemId());
            }
            pd.add(db);
        }
        bo.setCategoryId(27972);  //类型
        bo.setDetails(pd);
        bo.setBillTypeId(asnMaster.getAsnType()); //711
        bo.setBillNo(asnMaster.getBillNo());
//        bo.setBillNo(codeRuleService.generateCode("OUT"));//单号--不可重复
        bo.setBillDate(DateUtils.getNowDateString());//时间`
        bo.setSourceBillTypeId(asnMaster.getBillType());//类型702
        return bo;
    }
}

